<?php
define('NO_UPDATE',true);
abstract class common{
	var 
			$tbl = '';		//tabla básica de la clase
	var	$f = array(),
			$m = array();
	
	function __construct() {
		
	}
	
	abstract function create_body();
	abstract function update_body($no_update_fields=array());
	abstract function delete_body();	

	function event($event_name,$description=''){
		add_event($event_name,$description /*.var_export($this,true)*/,get_class($this).(isset($this->id)?" ($this->id)":''));
	}

	function dbError($comment=''){
		$this->event('db_error',$comment);
	}
	
	public function __set($key, $value) {
		if (method_exists($this,'validate')){
			$value = call_user_func(array($this, 'validate'), $key, $value);
		}

		if (property_exists($this,$key)){
			eval('$this->'.$key.' = $value;');
		} elseif (array_key_exists($key,$this->f)) {
			$this->f[$key] = $value;
		} else {
			$this->f[$key] = $value;
			$this->event('property_created',$key);
		}
	}

	public function __get($key) {
		$return = NULL;
/*		if (property_exists($this,$key)){
			eval('$return = &$this->'.$key.';');
		}else*/if (is_array($this->f) && array_key_exists($key,$this->f) ){
			$return = &$this->f[$key];
		}else{
			$this->event('no_property_read',"La propiedad no existe: '$key'");
		}
		return $return;
	}
	
	public function __call($name, $arguments) {
		$return = NULL;
		if (method_exists($this->m, $name)){
			$return = call_user_func_array(array($this->m, $name), $arguments);
		//	echo "CALL TO \$".get_class($this)."->m['$name']";
		}elseif (property_exists($this,$name) || array_key_exists($name,$this->f)){
			if (!empty($arguments)){
				eval("\$this->$name = \$arguments[0];");
			}
			eval("\$return = \$this->$name;");
		}elseif (substr($name,0,4)=='the_' && (property_exists($this,substr($name,4)) || array_key_exists(substr($name,4),$this->f)) ){
			$prop_name = substr($name,4);
			if (!empty($arguments)){
				eval("\$this->$prop_name = array_shift(\$arguments);");
			}

//			echo "echo \$this->$prop_name(\$arguments);";
			eval("\$return = \$this->$prop_name;");
			eval("echo \$return;");
		}else{
			$return = false;
			$this->event('__call',"Intento a ejecutar el método no definido: '$name'");
		}
		return $return;
	}

	function create(){
		global $user;
		global $db;
		$return = false;
		$fields = $this->create_body();
		if ($fields != false){
			$fields = array_diff_key($fields,array('id'=>false));
			if (method_exists($this,'validate')){
				foreach($fields as $key=>&$value){
					$value = call_user_func(array($this, 'validate'), $key, $value);
				}
			}
			if (!empty($fields)){
				$fields['created_at'] = array('NOW()');
				$fields['created_by'] = block($user->login);
				$fields['updated_at'] = array('NOW()');
				$fields['created_by'] = block($user->login);
				if ($db->insert($this->tbl,$fields)){
					$this->id = $return = $db->insert_id();
				}
			}
		}
		return $return;
	}

	function update($no_update_fields = array()){
		global $user;
		global $db;
		$return = false;
		$fields = $this->update_body($no_update_fields);
		$fields = array_diff_key($fields,array('id'=>false),$no_update_fields);
		if (method_exists($this,'validate')){
			foreach($fields as $key=>&$value){
				$value = call_user_func(array($this, 'validate'), $key, $value);
			}
		}
		if ($fields){
			$fields['updated_at'] = array('NOW()');
			$fields['created_by'] = block($user->login);
			$return = $db->update($this->tbl,$fields,$this->id);
		}
		return $return;
	}

	function delete(){
		global $db;		
		$return = false;
		$real_delete = $this->delete_body();
		if ($real_delete){
			$return = $db->delete($this->tbl,$this->id);
		}
		return $return;
	}
	
	function url($echo=true,$id=null){
		$id = is_null($id) ? $this->id() : $id;
		$return = url.get_class($this).'/'.$id.'/';
		if ($echo){
			echo $return;
		}
		return $return;
	}
	function url_edit($echo=true,$id=null){
		$id = is_null($id) ? $this->id() : $id;
		$return = url.get_class($this).'_edit/'.$id.'/';
		if ($echo){
			echo $return;
		}
		return $return;
	}
}
?>